#!/bin/sh
#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
set +x
#@function: restre DB by rman.

SCRIPT_ROOT_PATH=$1
PID=$2
PARAM_NUM=$3
SCRIPTPID=$$


. "${SCRIPT_ROOT_PATH}/oracle_sbin_func.sh"
. "${SCRIPT_ROOT_PATH}/oracle_native_restore_func.sh"

#********************************define these for the functions of agent_sbin_func.sh********************************

# global var, for kill monitor
PARAM_CONTENT=`read_input_param "${PARAM_NUM}"`
test -z "$PARAM_CONTENT"              && exit_with_error "PARAM_FILE"



#********************************define these for the functions of agent_sbin_func.sh********************************

#############################################################
DBNAME=`get_value "${PARAM_CONTENT}" AppName`
DBINSTANCE=`get_value "${PARAM_CONTENT}" InstanceName`
DBUSER=`get_value "${PARAM_CONTENT}" UserName`
DBUSERPWD=`get_value "${PARAM_CONTENT}" Password`
ASMUSER=`get_value "${PARAM_CONTENT}" ASMUserName`
ASMUSERPWD=`get_value "${PARAM_CONTENT}" ASMPassword`
ASMSIDNAME=`get_value "${PARAM_CONTENT}" ASMInstanceName`
RECOVERTARGET=`get_value "${PARAM_CONTENT}" recoverTarget`
RECOVERPATH=`get_value "${PARAM_CONTENT}" recoverPath`
RECOVERORDER=`get_value "${PARAM_CONTENT}" recoverOrder`
RECOVERNUM=`get_value "${PARAM_CONTENT}" recoverNum`
BACKUP=`get_value "${PARAM_CONTENT}" DataPath`
ORA_DB_USER=`get_value "${PARAM_CONTENT}" OracleInstallUser`
ORACLE_BASE=`get_value "${PARAM_CONTENT}" AccessOracleBase`
ORACLE_HOME=`get_value "${PARAM_CONTENT}" AccessOracleHome`


test "$DBNAME" = "ERROR_PARAM_INVALID"                           && exit_with_error "DBNAME"
test "$DBINSTANCE" = "ERROR_PARAM_INVALID"                       && exit_with_error "DBINSTANCE"
test "$DBUSER" = "ERROR_PARAM_INVALID"                           && exit_with_error "DBUSER"
test "$ASMUSER" = "ERROR_PARAM_INVALID"                          && exit_with_error "ASMUSER"
test "$ASMSIDNAME" = "ERROR_PARAM_INVALID"                       && exit_with_error "ASMSIDNAME"
test "$RECOVERTARGET" = "ERROR_PARAM_INVALID"                    && exit_with_error "RECOVERTARGET"
test "$RECOVERPATH" = "ERROR_PARAM_INVALID"                      && exit_with_error "RECOVERPATH"
test "$RECOVERORDER" = "ERROR_PARAM_INVALID"                     && exit_with_error "RECOVERORDER"
test "$BACKUP" = "ERROR_PARAM_INVALID"                           && exit_with_error "BACKUP"

BACKUP_PATH_LIST=`redirect_backup_path "${BACKUP}"`
MAIN_BACKUP_PATH=`echo "${BACKUP_PATH_LIST}" | $MYAWK -F ";" '{print $1}'`
ADDITIONAL="${MAIN_BACKUP_PATH}/additional"

log_info "PID=${PID};DBINSTANCE=${DBINSTANCE};DBName=${DBNAME};DBUSER=${DBUSER};\
ASMInst=${ASMSIDNAME};ASMUSER=${ASMUSER};\
DataPath=$BACKUP;RECOVERPATH=${RECOVERPATH};\
RECOVERORDER=${RECOVERORDER};RECOVERNUM=${RECOVERNUM};\
ORACLE_BASE=${ORACLE_BASE};ORACLE_HOME=${ORACLE_HOME}."


#********************************check host enviroment begin********************************
get_oracle_user

get_oracle_user_shell_type

env_file_list=`get_user_env_file "${ORA_DB_USER}"`
if [ $? -ne 0 ] || [ -z "$env_file_list" ]; then
    log_error "Get user env file failed"
    exit "$RETURN_INVALID"
fi

EXPORT_ORACLE_ENV=`generate_export_cmd "$env_file_list" "oracle"`
if [ $? -ne 0 ] || [ -z "$EXPORT_ORACLE_ENV" ]; then
    log_error "Get user env cmd failed"
    exit "$RETURN_INVALID"
fi

check_oracle_is_install

check_oracle_install_type

if [ "$DBISCLUSTER" -gt 0 ]; then
    get_grid_user
    # get grid user shell type
    get_grid_user_shell_type
    # get grid home path
    get_grid_home_path

    env_file_list=`get_user_env_file "${ORA_GRID_USER}"`
    if [ $? -ne 0 ] || [ -z "$env_file_list" ]; then
        log_error "Get user env file failed"
        exit "$RETURN_INVALID"
    fi

    EXPORT_GRID_ENV=`generate_export_cmd "$env_file_list" "grid"`
    if [ $? -ne 0 ] || [ -z "$EXPORT_GRID_ENV" ]; then
        log_error "Get user env cmd failed"
        exit "$RETURN_INVALID"
    fi
    ASMSIDNAME=`ps -ef | grep asm_...._+ | grep -v grep | ${MYAWK} -F_ '{print $NF}' | uniq`
    if [ -z "$ASMSIDNAME" ]; then
        log_error "Have no asm instance"
        exit "${RETURN_INVALID}"
    fi
fi

get_oracle_base_path

get_oracle_home_path

get_oracle_version

check_sqlplus_status

check_rman_status

get_instance_auth_type "${DBINSTANCE}"
AUTH_TYPE=$?


#********************************function define begin********************************
build_move_non_cdb_sql()
{
    for line in `cat "${DATA_FILES}"`; do
        con_id=`echo "$line" | ${MYAWK} -F ";" '{print $1}'`
        tablespace_name=`echo "$line" | ${MYAWK} -F ";" '{print $2}'`
        fileno=`echo "$line" | ${MYAWK} -F ";" '{print $3}'`
        dbfFullPath=`echo "$line" | ${MYAWK} -F ";" '{print $4}'`
        TSRealName=`ls "${MAIN_BACKUP_PATH}"/"${fileno}"/FNO-"${fileno}"_TS-*.dbf | grep -i "$tablespace_name" | $MYAWK -F '/' '{print $NF}'`
        [ -z "$TSRealName" ] && exit_with_error "get tablespace name is empty. "
        log_info "TSRealName=${TSRealName};dbfFullPath=${dbfFullPath}"
        if [ -f "$dbfFullPath" ] ; then
            rm -rf "$dbfFullPath" >> "${LOG_FILE_NAME}" 2>& 1
        fi
        if [ "${OMF_ENABLE}" -eq 0 ]; then
            if [ -z "${RECOVERPATH}" ]; then
                echo "alter database move datafile '${MAIN_BACKUP_PATH}/${fileno}/${TSRealName}' to '${dbfFullPath%/*}/${TSRealName}' REUSE KEEP;" >> "$1"
            else
                create_dir "${RECOVERPATH}/datafile"
                echo "alter database move datafile '${MAIN_BACKUP_PATH}/${fileno}/${TSRealName}' to '${RECOVERPATH}/datafile/${TSRealName}' REUSE KEEP;" >> "$1"
            fi
        else
            if [ -z "${RECOVERPATH}" ]; then
                if [ `rd_substr "${dbfFullPath}" 1 1` = "+" ]; then
                    echo "alter session set db_create_file_dest='${dbfFullPath%%/*}';" >> "$1"
                fi
            else
                if [ `rd_substr "${RECOVERPATH}" 1 1` = "+" ]; then
                    echo "alter session set db_create_file_dest='${RECOVERPATH%%/*}';" >> "$1"
                fi
            fi
            echo "alter database move datafile ${fileno};" >> "$1"
        fi
    done
    echo "exit;" >> "$1"
}

build_move_cdb_sql()
{
    for line in `cat "${DATA_FILES}"`; do
        con_id=`echo "$line" | ${MYAWK} -F ";" '{print $1}'`
        tablespace_name=`echo "$line" | ${MYAWK} -F ";" '{print $2}'`
        fileno=`echo "$line" | ${MYAWK} -F ";" '{print $3}'`
        dbfFullPath=`echo "$line" | ${MYAWK} -F ";" '{print $4}'`
        get_pdb_name_by_conid "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}" "${con_id}"
        if [ -n "${ORA_PDB_NAME}" ]; then
            echo "alter session set CONTAINER=${ORA_PDB_NAME};" >> "$1"
        fi
        TSRealName=`ls "${MAIN_BACKUP_PATH}"/"${fileno}"/FNO-"${fileno}"_TS-*.dbf | grep -i "$tablespace_name" | $MYAWK -F '/' '{print $NF}'`
        [ -z "$TSRealName" ] && exit_with_error "get tablespace name is empty. "
        log_info "TSRealName=${TSRealName};dbfFullPath=${dbfFullPath}"
        if [ -f "$dbfFullPath" ] ; then
            rm -rf "$dbfFullPath" 
        fi
        if [ "${OMF_ENABLE}" -eq 0 ]; then
            if [ -z "${RECOVERPATH}" ]; then
                echo "alter database move datafile '${MAIN_BACKUP_PATH}/${fileno}/${TSRealName}' to '${dbfFullPath%/*}/${TSRealName}' REUSE KEEP;" >> "$1"
            else
                create_dir "${RECOVERPATH}/datafile"
                echo "alter database move datafile '${MAIN_BACKUP_PATH}/${fileno}/${TSRealName}' to '${RECOVERPATH}/datafile/${TSRealName}' REUSE KEEP;" >> "$1"
            fi
        else
            if [ -z "${RECOVERPATH}" ]; then
                if [ `rd_substr ${dbfFullPath} 1 1` = "+" ]; then
                    echo "alter session set db_create_file_dest='${dbfFullPath%%/*}';" >> "$1"
                fi
            else
                if [ `rd_substr ${RECOVERPATH} 1 1` = "+" ]; then
                    echo "alter session set db_create_file_dest='${RECOVERPATH%%/*}';" >> "$1"
                fi
            fi
            echo "alter database move datafile ${fileno};" >> "$1"
        fi
    done
    echo "exit;" >> "$1"
}

move_dbf_online()
{
    # alter database move datafile  '/export/home/oracle/user01.dbf' to '+NEWTST/TESTDB2/DATAFILE/user01.dbf';
    instance_name=$1
    db_user=$2
    db_password=$3

    tmp_sql="${STMP_PATH}/MoveDBFOnline${PID}.sql"
    tmp_rst="${STMP_PATH}/MoveDBFOnlineRST${PID}.txt"
    log_info "Begin to move data online."
    
    if [ "${ORACLE_IS_CDB}" = "0" ]; then
        build_move_cdb_sql "${tmp_sql}"
    else
        build_move_non_cdb_sql "${tmp_sql}"
    fi
    chown "$ORA_DB_USER":"$ORA_DB_GROUP" "${tmp_sql}"
    chmod 700 "${tmp_sql}"

    oracle_exe_sql "${db_user}" "${db_password}" "${tmp_sql}" "${tmp_rst}" "${instance_name}" -1 1
    ret_code=$?
    if [ "$ret_code" -ne "0" ]; then
        log_error "Move dbf Online failed, ret=$ret_code"
        delete_file "${tmp_sql}" "${tmp_rst}" "true"
        exit ${ret_code}
    fi
    delete_file "${tmp_sql}" "${tmp_rst}" "true"
}
#********************************function define end********************************

#1. copy datafiles
DATA_FILES="$ADDITIONAL/dbfiles"

#2. check if is CDB
check_database_cdb_type "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}" 

#3. open pdb while status is mounted. When pdb status is mounted, it can't move datafile online.
if [ "${ORACLE_IS_CDB}" = "0" ]; then
    open_all_pdbs "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"
fi

check_omf_eable "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"

#4. movefile online
move_dbf_online "${DBINSTANCE}" "${DBUSER}" "${DBUSERPWD}"

if [ "${RECOVERTARGET}" -eq 2 ]; then
    grep "${DBINSTANCE}" /etc/oratab
    if [ $? -ne 0 ]; then
        echo "$DBINSTANCE"":""$IN_ORACLE_HOME"":N" >> /etc/oratab
    fi
fi

log_info "Move data online success."
exit 0